package icedot.library.common.utils;

import icedot.library.common.base.Logger;
import icedot.library.common.utils.struct.ContactInfo;
import icedot.library.common.utils.struct.PhoneInfo;
import icedot.library.common.utils.struct.ScreenInfo;
import icedot.library.common.utils.struct.SimInfo;
import icedot.library.common.utils.struct.StorageInfo;
import icedot.library.common.utils.struct.SysVersionInfo;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.provider.ContactsContract;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.Log;

public class SysServiceUtils
{
    /**
     * 网络是否连接
     * 
     * @return
     */
    public static boolean isConnect(Context context)
    {
        NetworkInfo info = getNetWorkState(context);
        if (info == null)
            return false;
        // WIFI网络
        switch (info.getType())
        {
        case ConnectivityManager.TYPE_WIFI:
            return true;
        case ConnectivityManager.TYPE_MOBILE:
            return true;
            // case ConnectivityManager.TYPE_BLUETOOTH: //蓝牙
            // return false;
            // case ConnectivityManager.TYPE_DUMMY: //
            // return false;
        case ConnectivityManager.TYPE_ETHERNET: // 以太网
            return true;
        case ConnectivityManager.TYPE_MOBILE_DUN:
            return false;
        case ConnectivityManager.TYPE_WIMAX:
            return false;
        default:
            return false;
        }
    }

    /**
     * 获取手机网络状态
     * 
     * @return
     */
    public static NetworkInfo getNetWorkState(Context context)
    {
        if(context == null)
        {
            return null;
        }
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo();
    }

    /**
     * 获取SIM状态
     */
    public static SimInfo getSimInfo(Context context)
    {
        if(context == null)
        {
            return null;
        }
        SimInfo info = new SimInfo();
        TelephonyManager tm = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);
        info.setState(tm.getSimState());
        info.setDescription(getSIMDesc(info));
        info.setKey(tm.getSimSerialNumber());

        return info;
    }

    /**
     * 获取 SIM的文字描述
     *
     */
    private static String getSIMDesc(SimInfo info)
    {
        switch (info.getState())
        {
        case TelephonyManager.SIM_STATE_ABSENT:
            return "无SIM卡";
        case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
            return "需要NetworkPIN解锁";
        case TelephonyManager.SIM_STATE_PIN_REQUIRED:
            return "需要PIN解锁";
        case TelephonyManager.SIM_STATE_PUK_REQUIRED:
            return "需要PUK解锁";
        case TelephonyManager.SIM_STATE_READY:
            return "SIM正常";
        default:
            return "未知状态";
        }
    }

    /**
     * 测试GPS是否打开
     * 
     * @return
     */
    public static boolean isGpsOpen(Context context)
    {
        if (context == null)
            return false;
        LocationManager lm = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        if (lm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER))
        {
            return true;
        } else
        {
            return false;
        }
    }

    /**
     * 获取手机和SIM卡里的联系人信息
     * 
     * @param context
     * @return
     */
    public static List<ContactInfo> getContacts(Context context)
    {
        if(context == null)
        {
            return null;
        }
        List<ContactInfo> contactList = new ArrayList<ContactInfo>();
        Cursor cur = null;
        try {

            // 获得所有的联系人
            cur = context.getContentResolver().query(
                    ContactsContract.Contacts.CONTENT_URI,
                    null,
                    null,
                    null,
                    ContactsContract.Contacts.DISPLAY_NAME
                            + " COLLATE LOCALIZED ASC");
            // 循环遍历
            if (cur.moveToFirst()) {
                int idColumn = cur.getColumnIndex(ContactsContract.Contacts._ID);
                int displayNameColumn = cur
                        .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
                do {
                    ContactInfo user = new ContactInfo();
                    // 获得联系人的ID号
                    user._id = cur.getString(idColumn);
                    // 获得联系人姓名
                    user._name = cur.getString(displayNameColumn);
                    // 查看该联系人有多少个电话号码。如果没有这返回值为0
                    int phoneCount = cur
                            .getInt(cur
                                    .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
                    if (phoneCount > 0) {
                        // 获得联系人的电话号码
                        Cursor phones = context.getContentResolver().query(
                                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                null,
                                ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                        + " = " + user._id, null, null);
                        if (phones.moveToFirst()) {
                            do {
                                // 遍历所有的电话号码
                                PhoneInfo phoneInfo = new PhoneInfo();
                                phoneInfo._phone = phones
                                        .getString(phones
                                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                                phoneInfo._type = phones
                                        .getString(phones
                                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
                                user._phoneList.add(phoneInfo);
                            } while (phones.moveToNext());
                            if (user._phoneList.size() > 0) {
                                contactList.add(user);
                            }
                        }
                    }

                } while (cur.moveToNext());
            }
            return contactList;
        }
        catch (Exception e)
        {
            Logger.showDebugMsg(Logger.s_error,"Exception",e.getMessage());
            return contactList;
        }
        finally {
            if(cur != null)
            {
                cur.close();
                cur = null;
            }
        }
    }

    /**
     * 获取手机和SIM卡里的联系人信息
     *
     * @param context
     * @return
     */
    public static boolean getContacts(Context context,List<ContactInfo> contactList)
    {
        if(context == null || contactList==null)
        {
            return false;
        }
        Cursor cur = null;
        Cursor phones = null;
        try
        {
            // 获得所有的联系人
            cur = context.getContentResolver().query(
                    ContactsContract.Contacts.CONTENT_URI,
                    null,
                    null,
                    null,
                    ContactsContract.Contacts.DISPLAY_NAME
                            + " COLLATE LOCALIZED ASC");
            // 循环遍历
            if (cur.moveToFirst()) {
                int idColumn = cur.getColumnIndex(ContactsContract.Contacts._ID);
                int displayNameColumn = cur
                        .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
                do {
                    ContactInfo user = new ContactInfo();
                    // 获得联系人的ID号
                    user._id = cur.getString(idColumn);
                    // 获得联系人姓名
                    user._name = cur.getString(displayNameColumn);
                    // 查看该联系人有多少个电话号码。如果没有这返回值为0
                    int phoneCount = cur
                            .getInt(cur
                                    .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
                    if (phoneCount > 0) {
                        // 获得联系人的电话号码
                        phones = context.getContentResolver().query(
                                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                null,
                                ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                        + " = " + user._id, null, null);
                        if (phones != null && phones.moveToFirst()) {
                            do {
                                // 遍历所有的电话号码
                                PhoneInfo phoneInfo = new PhoneInfo();
                                phoneInfo._phone = phones
                                        .getString(phones
                                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                                phoneInfo._type = phones
                                        .getString(phones
                                                .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
                                user._phoneList.add(phoneInfo);
                            } while (phones.moveToNext());
                            if (user._phoneList.size() > 0) {
                                contactList.add(user);
                            }
                        }
                        if (phones != null) {
                            phones.close();
                            phones = null;
                        }
                    }

                } while (cur.moveToNext());
            }
            return true;
        }
        catch (Exception e)
        {
            Logger.showDebugMsg(Logger.s_error,"Exception",e.getMessage());
            return false;
        }
        finally {
            if(cur != null)
            {
                cur.close();
                cur = null;
            }
            if(phones !=null)
            {
                phones.close();
                phones = null;
            }
        }
    }

    /**
     * 获取系统的SD卡和系统的存储空间
     * 
     * @return
     */
    @SuppressWarnings("deprecation")
    @SuppressLint("NewApi")
    public static StorageInfo getStorageInfo(Context context)
    {
        if (context == null)
            return null;
        StorageInfo storage = new StorageInfo();
        // 是否有SD卡
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED))
        {
            storage.setHaveSD(true);
        } else
        {
            storage.setHaveSD(false);
        }

        // storage.setCurrentPath(Environment.getDownloadCacheDirectory().getAbsolutePath());
        // 获取SD卡的信息
        if (storage.haveSD())
        {
            storage.setSDPath(Environment.getExternalStorageDirectory()
                    .getAbsolutePath());
            StatFs statfs = new StatFs(storage.getSDPath());
            if (android.os.Build.VERSION.SDK_INT >= 18)
            {
                storage.setSDBlockSize(statfs.getBlockSizeLong());
                storage.setSDBlockTotal(statfs.getBlockCountLong());
                storage.setSDBlockIdle(statfs.getAvailableBlocksLong());
            } else
            {
                storage.setSDBlockSize(statfs.getBlockSize());
                storage.setSDBlockTotal(statfs.getBlockCount());
                storage.setSDBlockIdle(statfs.getAvailableBlocks());
            }
        }

        // 获取系统的空间
        String appPath = context.getCacheDir().getAbsolutePath();
        appPath = appPath.substring(0, appPath.lastIndexOf("/"));
        storage.setCurrentPath(appPath);
        StatFs sysstatfs = new StatFs(storage.getCurrentPath());
        if (android.os.Build.VERSION.SDK_INT >= 18)
        {
            storage.setSysBlockSize(sysstatfs.getBlockSizeLong());
            storage.setSysBlockTotal(sysstatfs.getBlockCountLong());
            storage.setSysBlockIdle(sysstatfs.getAvailableBlocksLong());
        } else
        {
            storage.setSysBlockSize(sysstatfs.getBlockSize());
            storage.setSysBlockTotal(sysstatfs.getBlockCount());
            storage.setSysBlockIdle(sysstatfs.getAvailableBlocks());
        }

        return storage;
    }

    /**
     * 获取系统的安卓版本
     * 
     * @return
     */
    public static SysVersionInfo getAndroidVersion(Context context)
    {
        if(context == null)
        {
            return null;
        }
        SysVersionInfo info = new SysVersionInfo();
        info.setPhoneType(android.os.Build.MODEL);
        info.setAndroidSDK(android.os.Build.VERSION.SDK_INT);
        info.setAndroidRelease(android.os.Build.VERSION.RELEASE);

        try
        {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(
                    context.getPackageName(), 0);
            info.setAppCode(packageInfo.versionCode);
            info.setAppVersion(packageInfo.versionName);
            info.setAppPackName(packageInfo.packageName);
        } catch (NameNotFoundException e)
        {
            Logger.showDebugMsg(Logger.s_error, "Exception", e.getMessage());
        }

        return info;
    }

    /**
     * 启用被禁用组件方法
     * 
     * @param context
     * @param componentName
     */
    public static void enableComponentIfNeeded(Context context,
            String componentName)
    {
        if(context == null)
        {
            return;
        }
        
        PackageManager pmManager = context.getPackageManager();
        if (pmManager != null)
        {
            ComponentName cnComponentName = new ComponentName(
                    context.getPackageName(), componentName);
            int status = pmManager.getComponentEnabledSetting(cnComponentName);
            if (status != PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
            {
                pmManager.setComponentEnabledSetting(cnComponentName,
                        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                        PackageManager.DONT_KILL_APP);
            }
        }
    }

    /**
     * 获取手机屏幕的尺寸
     * 
     * @param context
     * @return
     */
    public static ScreenInfo getScreenSize(Context context)
    {
        if(context == null)
        {
            return null;
        }
        ScreenInfo size = new ScreenInfo();
        DisplayMetrics dm = context.getResources().getDisplayMetrics();
        size._width = dm.widthPixels;
        size._height = dm.heightPixels;
        size._dpi = dm.densityDpi;

        return size;
    }

    public static String getDevicesID(Context context)
    {
        try
        {
            WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            WifiInfo info = wifi.getConnectionInfo();
            return info.getMacAddress();
        }
        catch(Exception e)
        {
            return "Can'tGetMACAddress";
        }
    }

    /**
     * 拨打电话
     * @param context
     */
    public static void jumpTocall(final Context context,String phone)
    {
        try
        {
            String action = Intent.ACTION_CALL;// 显示拨号界面
            Intent intent = new Intent(action, Uri.parse("tel:" + phone));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intent);
        }
        catch (SecurityException e)
        {
            Logger.errorMsg(e.getMessage());
        }
    }

    /**
     * 发送短信
     * @param context
     * @param phone
     * @param content
     */
    public static void jumpToMsg(final Context context,String phone,String content)
    {
        Uri uri = Uri.parse("smsto:" + phone);
        Intent intent = new Intent(Intent.ACTION_SENDTO,uri);
        intent.putExtra("sms_body", content);
        context.startActivity(intent);
    }

    /**
     * Get a file path from a Uri. This will get the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     * @author paulburke
     */
    @SuppressLint("NewApi")
    public static String getPathFromUri(final Context context, final Uri uri)
    {

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri))
        {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri))
            {
                final String   docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String   type  = split[0];

                if ("primary".equalsIgnoreCase(type))
                {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri))
            {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri))
            {
                final String   docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String   type  = split[0];

                Uri contentUri = null;
                if ("image".equals(type))
                {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                }
                else if ("video".equals(type))
                {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                }
                else if ("audio".equals(type))
                {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{split[1]};

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme()))
        {
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme()))
        {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     */
    public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs)
    {

        Cursor       cursor = null;
        final String column = "_data";
        final String[] projection = {column};

        try
        {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst())
            {
                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        }
        finally
        {
            if (cursor != null) cursor.close();
        }
        return null;
    }


    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    public static boolean isExternalStorageDocument(Uri uri)
    {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    public static boolean isDownloadsDocument(Uri uri)
    {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    public static boolean isMediaDocument(Uri uri)
    {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }
}
